home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / CH_3.3 / BC / BC.C next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  5.4 KB  |  208 lines

  1. /* 
  2.  * bc.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /*
  10.  * BC (background correction)
  11.  *
  12.  *  Divides the input image by the reference image
  13.  *  (to correct for nonuniform background and shading), scales 
  14.  *  the result and wrtes the image to the specified output file
  15.  *   
  16.  */
  17.  
  18. #include "bc.h"
  19.  
  20. #define  NOLOOP        0
  21. #define INDEX_SCALE 255
  22.  
  23. #define     ON        1
  24. #define     OFF        0
  25.  
  26. /*
  27.  * global variables
  28.  */
  29. extern char *optarg;
  30. extern int optind, opterr;
  31. extern short tiffInput;         /* flag=0 if no ImageIn to set tags; else =1 */
  32.  
  33. int BINARIZE = OFF;
  34.  
  35. /*
  36.  * usage of routine
  37.  */
  38. void
  39. usage (char *progname)
  40. {
  41.   progname = last_bs (progname);
  42.   printf ("USAGE: %s in1img in2img outimg [-c clip][-b][-L]\n", progname);
  43.   printf ("\n%s divides the first input image by the second input image\n", progname);
  44.   printf ("(to correct for nonuniform background and shading), scales\n");
  45.   printf ("the result and writes the image to the specified output file.\n\n");
  46.   printf ("ARGUMENTS:\n");
  47.   printf ("   in1img: first input image filename (TIF)\n");
  48.   printf ("   in2img: second input image filename (TIF)\n");
  49.   printf ("   outimg: output image filename (TIF)\n\n");
  50.   printf ("OPTIONS:\n");
  51.   printf ("  -c clip: clipping factor for normalized image 0-255(default=1)\n");
  52.   printf ("       -b: generate binarized output by conversion to integer\n");
  53.   printf ("       -L: print Software License for this module\n");
  54.   exit (1);
  55. }
  56.  
  57. /*
  58.  *  background correction
  59.  *   divide active image by reference image and scale to 255
  60.  *   reference: S. Inoue, "Video Microscopy", chapt. 10
  61.  */
  62. void
  63. backgrd_correct (Image * imgIn, Image * imgRef, Image * imgOut, int clip_factor, int binarize)
  64. {
  65.   int ix, iy;
  66.   int max_x, max_y;
  67.   float pixelIn, pixelRef;
  68.   float norm_pix = (float) 0.0;
  69.   float norm_pix_max = (float) 0.0;
  70.   int j;
  71.  
  72.   max_y = ImageGetHeight (imgIn);
  73.   max_x = ImageGetWidth (imgIn);
  74.   for (ix = 0; ix < max_x; ix++) {
  75.     for (iy = 0; iy < max_y; iy++) {
  76.       pixelIn = (float) (getpixel (ix, iy, imgIn));
  77.       pixelRef = (float) (getpixel (ix, iy, imgRef));
  78.       pixelRef = (pixelRef + (float) 1 > (float) INDEX_SCALE) ? (float) INDEX_SCALE : pixelRef + (float) 1;
  79.       if (pixelRef < 2.0)
  80.         continue;
  81.       if (clip_factor) {
  82.         norm_pix = (pixelIn / pixelRef > (float) clip_factor) ? (float) clip_factor : pixelIn / pixelRef;
  83.         if (binarize)
  84.           setpixel (ix, iy, imgOut, (int) (INDEX_SCALE * (int) (norm_pix + 0.5)));
  85.         else
  86.           setpixel (ix, iy, imgOut, (int) norm_pix);
  87.       }
  88.       else {                    /*just get the maximum normalized pixel */
  89.         norm_pix = pixelIn / pixelRef;
  90.         if (norm_pix > norm_pix_max)
  91.           norm_pix_max = norm_pix;
  92.       }
  93.     }
  94.   }
  95.   /*
  96.    * if there was no clipping factor specified,
  97.    * we just calculated the maximum normalized pixel value
  98.    * now scale the image according to norm_pix_max
  99.    */
  100.   if (!clip_factor) {
  101.     for (ix = 0; ix < max_x; ix++) {
  102.       for (iy = 0; iy < max_y; iy++) {
  103.         if (ix > 100 && iy > 100)
  104.           j = 0;
  105.         pixelIn = (float) (getpixel (ix, iy, imgIn));
  106.         pixelRef = (float) (getpixel (ix, iy, imgRef));
  107.         pixelRef = (pixelRef + (float) 1 > (float) INDEX_SCALE) ? (float) INDEX_SCALE : pixelRef + (float) 1;
  108.         norm_pix = pixelIn / (pixelRef * norm_pix_max);
  109.         if (binarize)
  110.           setpixel (ix, iy, imgOut, (int) (INDEX_SCALE * (int) (norm_pix + 0.5)));
  111.         else
  112.           setpixel (ix, iy, imgOut, (norm_pix > 1.0 ? INDEX_SCALE : (int) (INDEX_SCALE * norm_pix)));
  113.       }
  114.     }
  115.   }
  116. }
  117.  
  118. void
  119. main (int argc, char *argv[])
  120. {
  121.   Image *imgIn;
  122.   Image *imgOut;
  123.   Image *imgRef;
  124.  
  125.   int i_arg;
  126.   int clip_factor = 0;
  127.   int binarize = 0;
  128.  
  129. /*
  130.  * cmd line options
  131.  */
  132.   static char *optstring = "c:bL";
  133.  
  134.  
  135. /*
  136.  * parse command line
  137.  */
  138.   optind = 4;                   /* set getopt to point to the 4th arg */
  139.   opterr = ON;                  /* give error messages */
  140.  
  141.  
  142.   if (argc < 4)
  143.     usage (argv[0]);
  144.  
  145.   while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
  146.     switch (i_arg) {
  147.     case 'b':
  148.       printf ("\n...option %c: generate binary output\n", i_arg);
  149.       binarize = 1;
  150.       break;
  151.     case 'c':
  152.       if ((clip_factor = atoi (optarg)) > 255) {
  153.         printf ("Clipping factor must be <= 255\n");
  154.         printf ("Defaulting to calculated clipping factor\n");
  155.         clip_factor = 0;
  156.       }
  157.       break;
  158.     case 'L':
  159.       print_sos_lic ();
  160.       exit (0);
  161.     default:
  162.       printf ("\ngetopt: unknown condition encountered\n");
  163.       exit (1);
  164.       break;
  165.     }
  166.   }
  167.  
  168. /*
  169.  * Read input image
  170.  */
  171.   imgIn = ImageIn (argv[1]);
  172.  
  173.   if (imgIn->bps == 8 && imgIn->spp == 3) {
  174.     printf ("Got RGB image!!!\nInput image must be Grayscale or B&W!!\n");
  175.     exit (1);
  176.   }
  177. /*
  178.  * Read reference image
  179.  */
  180.   imgRef = ImageIn (argv[2]);
  181.  
  182.   if (ImageGetHeight (imgIn) != ImageGetHeight (imgRef) ||
  183.       ImageGetWidth (imgIn) != ImageGetWidth (imgRef)) {
  184.     printf ("Input and Reference images cannot have different sizes\n");
  185.     exit (1);
  186.   }
  187.  
  188. /*
  189.  * Allocate memory for output image
  190.  */
  191.   imgOut = ImageAlloc ((long) ImageGetHeight (imgIn), (long) ImageGetWidth (imgIn), (long) BPS);
  192.  
  193. /*
  194.  * perform background illumination correction 
  195.  */
  196.   backgrd_correct (imgIn, imgRef, imgOut, clip_factor, binarize);
  197.  
  198. /* 
  199.  * reset tiffInput so that we write a grayscale file (i.e tags are not copied)
  200.  */
  201.   tiffInput = 0;
  202.  
  203. /*
  204.  * Write the output image
  205.  */
  206.   ImageOut (argv[3], imgOut);
  207. }
  208.